const express = require('express');
const {Base64} = require('../libs/base64js');
const {UUID} = require('../libs/utils');
const fs = require('fs');
// Date.prototype.toJSON = function () {
//     var timezoneOffsetInHours = -(this.getTimezoneOffset() / 60); //UTC minus local time
//     var sign = timezoneOffsetInHours >= 0 ? '+' : '-';
//     var leadingZero = (Math.abs(timezoneOffsetInHours) < 10) ? '0' : '';
//
//     //It's a bit unfortunate that we need to construct a new Date instance
//     //(we don't want _this_ Date instance to be modified)
//     var correctedDate = new Date(this.getFullYear(), this.getMonth(),
//         this.getDate(), this.getHours(), this.getMinutes(), this.getSeconds(),
//         this.getMilliseconds());
//     correctedDate.setHours(this.getHours() + timezoneOffsetInHours);
//     var iso = correctedDate.toISOString().replace('Z', '').replace('T',' ').replace(/\.[\d]+/g,'');
//
//     return iso;
// };
function api(_, fileUpload, db, jwt){
    var router = express.Router();

    /* GET home page. */
    router.get('/:table/:id', function(req, res, next) {
        let table = req.params.table;
        let id = req.params.id;
        let list = db.list(table,1,null,{___id:id});
        if(!list){
            list={};
        }
        res.status(200).send(JSON.stringify(list[0]));
    });
    router.get('/:table', function(req, res, next) {
        let table = req.params.table;
        let size = req.query.size || 30;
        let page = req.query.page || 0;
        let conditions = (req.query.conditions?(JSON.parse(req.query.conditions)):null) || null;
        let sort = req.query.sort || null;
        let list = db.list(table,size,page,conditions,sort);
        if(!list){
            list=[];
        }
        res.status(200).send(JSON.stringify(list));
    });
    router.post('/:table', function(req, res, next) {
        let table = req.params.table;
        let params = req.body;
        let size = params['size'] || 30;
        let page = params['page'] || 0;
        let conditions = params['conditions'] || null;
        let sort = params['sort'] || null;
        let joins = params['joins'] || null;
        let list = db.list(table,size,page,conditions,sort,joins);
        if(!list){
            list=[];
        }
        res.status(200).send(JSON.stringify(list));
    });
    function updateItem(item,table){
        item.updated = new Date();
        delete item.___id;
        if(item.imagesData){
            let i,img,filename,writer,arr,tstr, path;
            path = __dirname + '/../upload/'+table+'/';
            !fs.existsSync(path) && fs.mkdir(path, { recursive: true }, (err) => {
                if (err) throw err;
            });
            for(i in item.imagesData){
                img = item.imagesData[i];
                filename = UUID()+'_'+img.file;
                writer = fs.createWriteStream(path+filename);
                tstr = img.data.replace(/^(data[^,]+,)/ig,'');
                arr = Base64.atob(tstr);
                arr = new Uint8Array([...arr].map(char => char.charCodeAt(0)));
                writer.write(arr);
                writer.close();
                item.images[i] = filename;
            }
            delete item.imagesData;
        }
    }
    router.put('/:table/:id', function(req, res, next) {
        let table = req.params.table;
        let id = req.params.id;
        let items = req.body,item,i;
        if(items instanceof Array){
            for(i=0;i<items.length;i++){
                item = items[i];
                updateItem(item,table);
            }
        }else{
            item = items;
            updateItem(item,table);
        }

        let rst = db.update(table,{___id:id},items);
        res.status(200).send(JSON.stringify(rst));
    });
    router.get('/:table/image/:file', function(req, res, next) {
        let table = req.params.table;
        let path = __dirname + '/../upload/'+table+'/';
        let file = req.params['file'];
        res.download(path+file);
    });
    function newItem(item,table){
        let i,img,filename,writer,arr,tstr, path;
        path = __dirname + '/../upload/'+table+'/';
        !fs.existsSync(path) && fs.mkdir(path, { recursive: true }, (err) => {
            if (err) throw err;
        });
        for(i in item.imagesData){
            img = item.imagesData[i];
            filename = UUID()+'_'+img.file;
            writer = fs.createWriteStream(path+filename);
            tstr = img.data.replace(/^(data[^,]+,)/ig,'');
            arr = Base64.atob(tstr);
            arr = new Uint8Array([...arr].map(char => char.charCodeAt(0)));
            writer.write(arr);
            writer.close();
            item.images[i] = filename;
        }
        delete item.imagesData;
        item.created = new Date();
    }
    router.post('/:table/save',(req, res, next)=>{
        let table = req.params.table;
        let items = req.body,item,i;
        if(items instanceof Array){
            for(i=0;i<items.length;i++){
                item = items[i];
                newItem(item,table);
            }
        }else{
            item = items;
            newItem(item,table);
        }
        let list = db.insert(table,items);
        res.status(200).send(JSON.stringify(list));
    });
    router.post('/:table/merge/:key',(req, res, next)=>{
        let table = req.params.table;
        let key = req.params.key;
        let items = req.body,item,i;
        if(items instanceof Array){
            for(i=0;i<items.length;i++){
                item = items[i];
                newItem(item,table);
            }
        }else{
            item = items;
            newItem(item,table);
        }
        let list = db.merge(table,items,key);
        res.status(200).send(JSON.stringify(list));
    });

    router.post('/:table/update',(req, res, next)=>{
        let table = req.params.table;
        let items = req.body,item,i;
        let uitems = [];
        let nitems = [];
        if(items instanceof Array){
            for(i=0;i<items.length;i++){
                item = items[i];
                if(!item.___id){
                    newItem(item,table);
                    nitems.push(item);
                }else{
                    let id = item.___id;
                    updateItem(item,table);
                    let rst = db.update(table,{___id:id},item);
                    uitems.push(rst[0]);
                }
            }
        }else{
            item = items;
            if(!item.___id){
                newItem(item,table);
                nitems.push(item);
            }else{
                let id = item.___id;
                updateItem(item,table);
                let rst = db.update(table,{___id:id},item);
                uitems.push(rst[0]);
            }
        }
        let list = [];
        if(nitems.length>0) {
            list = db.insert(table,nitems);
        }
        if(uitems.length>0){
            list.splice(list.length,0,...uitems);
        }
        res.status(200).send(JSON.stringify(list));
    });
    router.delete('/:table/:ids',(req, res, next)=>{
        let table = req.params.table;
        let idst = req.params.ids;
        let ids = decodeURIComponent(idst).split(',');
        let condotion = {___id:ids};
        let list = [];
        list = db.delete(table,condotion);
        res.status(200).send(JSON.stringify(list));
    });
    router.post('/:table/delete',(req, res, next)=>{
        let table = req.params.table;
        let ids = req.body;
        let condotion = {___id:ids};
        let list = [];
        list = db.delete(table,condotion);
        res.status(200).send(JSON.stringify(list));
    });

    return router;
}

module.exports = api;
